﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Babylon.Toolbox;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Silverlight;
using Color = Microsoft.Xna.Framework.Color;

namespace Babylon.Toolkit.ParticlesSample
{
    public partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private OrbitCamera _camera;
        private ParticleSystem _smokeParticleSystem;
        private ParticleSystem _fireParticleSystem;
               
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            _camera = new OrbitCamera {Radius = 200};
            _camera.AttachTo(inputSurface);
            GraphicsDevice gd = GraphicsDeviceManager.Current.GraphicsDevice;
            ParticleSettings smokeSettings = new ParticleSettings();
            ParticleSettings explosionSettings = new ParticleSettings();

            Texture2D explostionTexture = LoadTexture("fire.png", gd);
            Texture2D smokeTexture = LoadTexture("smoke.png", gd);
            
            smokeSettings.MaxParticleCount = 600;
            explosionSettings.MaxParticleCount = 120;
            smokeSettings.Texture = smokeTexture;
            explosionSettings.Texture = explostionTexture;
            smokeSettings.BlendState = BlendState.AlphaBlend;
            explosionSettings.BlendState = BlendState.Additive;
            smokeSettings.ParticleAvgDuration = 10;
            explosionSettings.ParticleAvgDuration = 0.7f;
            smokeSettings.ParticleDurationRandomness = 0.2f;
            explosionSettings.ParticleDurationRandomness = 0.5f;
            smokeSettings.MinStartSize = 8;
            explosionSettings.MinStartSize = 3;
            smokeSettings.MaxStartSize = 15;
            explosionSettings.MaxStartSize = 6;
            smokeSettings.MinEndSize = 60;
            explosionSettings.MinEndSize = 35;
            smokeSettings.MaxEndSize = 140;
            explosionSettings.MaxEndSize = 98;
            smokeSettings.MinVelocityValues = new Vector3(-10,20,-10);
            smokeSettings.MaxVelocityValues = new Vector3(10, 25, 10);
            explosionSettings.MinVelocityValues = new Vector3(-25, 0, -25);
            explosionSettings.MaxVelocityValues = new Vector3(25, 25, 25);
            smokeSettings.EndVelocityRatio = 0.75f;
            explosionSettings.EndVelocityRatio = 1;
            smokeSettings.MinRotationSpeed = -1;
            smokeSettings.MaxRotationSpeed = 1;
            explosionSettings.MinRotationSpeed = -1;
            explosionSettings.MaxRotationSpeed = 1;
            smokeSettings.EnvironmentForces = new Vector3(0, -5, 20);
            explosionSettings.EnvironmentForces = new Vector3(5, 50, 0);
            smokeSettings.MinTeint = new Vector3(1, 1, 1);
            smokeSettings.MaxTeint = new Vector3(1, 1, 1);
            explosionSettings.MinTeint = new Vector3(1,0.5f,0.0f);
            explosionSettings.MaxTeint = new Vector3(1, 0.7f, 0.0f);

            _smokeParticleSystem = new ParticleSystem(gd, smokeSettings, new Vector3(0, 15, 0), null, 0);
            _fireParticleSystem = new ParticleSystem(gd, explosionSettings, Vector3.Zero, null, 0);
        }

        static Texture2D LoadTexture(string resource, GraphicsDevice gd)
        {
            var stream = Application.GetResourceStream(new Uri(resource, UriKind.Relative)).Stream;
            var bmp = new BitmapImage();
            bmp.SetSource(stream);

            
            Texture2D res = new Texture2D(gd, bmp.PixelWidth, bmp.PixelHeight, false, SurfaceFormat.Color);
            bmp.CopyTo(res);
            return res;
        }

        private int _frame;
        private float _aspectRatio;

        private void OnDraw(object sender, DrawEventArgs e)
        {
            _frame++;
            var gd = e.GraphicsDevice;

            gd.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(50, 100, 200, 255), 1, 0);
            gd.RasterizerState = RasterizerState.CullNone;

            var ellapsed = (float)e.TotalTime.TotalSeconds;
            _smokeParticleSystem.UpdateAndDraw(gd, ellapsed, _camera.View, _camera.Projection);
            _fireParticleSystem.UpdateAndDraw(gd, ellapsed, _camera.View, _camera.Projection);

            if (_frame % 2 == 0)
                _smokeParticleSystem.AddParticles(1, ellapsed);
           
            _fireParticleSystem.AddParticles(1, ellapsed);

            _camera.ApplyInertia();

            e.InvalidateSurface();
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs e){
            _aspectRatio = (float)(e.NewSize.Width/e.NewSize.Height);
            _camera.AspectRatio = _aspectRatio;
        }
    }
}
